function E() { }
 
E.prototype = {
    on: function (name, callback, context) {
        var e = this.e || (this.e = {}); 
        (e[name] || (e[name] = [])).push({
                fn: callback,
                context
            })
        return this
    },
    // once函数：接收订阅名，订阅函数，上下文对象
    // 与on的区别是：once函数收集只执行一遍的订阅函数
    once: function (name, callback, context) {
        let self = this
        function listener() {
            self.off(name, listener)
            callback.apply(context, arguments)
        }
        listener._ = callback
        return this.on(name, listener, context)
    },
    // emit方法用于触发订阅函数：接收订阅名称
    emit: function (name) {
        let args = [].slice.call(arguments, 1)
        let events = ((this.e || (this.e = {}))[name] || []).slice()
 
        let i = 0
        let len = events.length
        for (; i < len; i++) {
            events[i].fn.apply(events[i].context, args)
        }
        return this
    },
    // off用于删除订阅函数：接收订阅名和订阅函数
    off: function (name, callback) {
        let e = this.e || (this.e = {})
        let events = e[name]
        let liveEvents = []
        if (events && callback) {
            for (let i = 0, len = events.length; i < len; i++) {
                if (events[i].fn !== callback && events[i].fn._ !== callback) {
                    liveEvents.push(events[i])
                }
            }
        }
        (liveEvents.length) ? e[name] = liveEvents : delete e[name]
        return this
    }
}
 
export default {
    $on: (...args) => E.prototype.on(...args),
    $once: (...args) => E.prototype.once(...args),
    $off: (...args) => E.prototype.off(...args),
    $emit: (...args) => E.prototype.emit(...args)
}